<?php

namespace MemFrameWork;

use \Memcache;

/**
 * memck short summary.
 *
 * memck description.
 *
 * @version 1.0
 * @author 张云江
 */
class Memck extends Mem
{
    /**
     * 缓存锁定
     */
    const LOCKKEY = "___MEMLOCK___";
    /**
     * Memcache对象
     * @var Memcache
     */
    private $memcache;
    /**
     * 构建memcache对象
     * @param array $viewrelatkey 关系键对象
     * @param string $dbname 数据库名
     * @param string $tablename 数据表名
     */
    public function __construct($viewrelatkey, $dbname, $tablename)
    {
        parent::__construct($viewrelatkey, $dbname, $tablename);
        $this->init();
    }
    /**
     * 解锁缓存
     * @return void
     */
    private function unlock()
    {
        if ($this->isEmptyWithConfig())
            return;
        if (!$this->lock_on)
            return;
        $this->memcache->set(self::LOCKKEY, 0);
    }
    /**
     * 锁定缓存
     * 如果有人使用缓存返回false
     * 否则返回true
     * @return bool
     */
    private function lock()
    {
        if ($this->isEmptyWithConfig())
            return true;
        if (!$this->lock_on)
            return true;
        $lock = (int)$this->memcache->get(self::LOCKKEY);
        if ($lock == 0) {
            $this->memcache->set(self::LOCKKEY, 1);
            return true;
        }
        return false;
    }

    /**
     * 清理缓存(继承函数)
     * @param mixed $nkey 每个要删除的key
     * @return array|null|string 已删除的键集合
     */
    protected function clean($nkey)
    {
        if ($this->isEmptyWithConfig())
            return null;
        $newnkey = str_ireplace("*", "", $nkey);
        $memarray = $this->memcache->get($newnkey);
        foreach (array_keys($memarray) as $key) {
            $this->memcache->delete($key);
        }
        return $memarray;
    }
    /**
     * 初始化
     * @return void
     */
    function init()
    {
        if (!class_exists("Memcache"))
            return;
        $memconfig = \Config\MemcacheConfig::getConfigWithAll();
        if ($memconfig) {
            // $this->memcache = new Memcache();
            /**
             * 每个配置对象array
             * @var $obj array
             */
            foreach ($memconfig as $key => $obj) {
                if ($key == "global") {
                    $iscon = $this->memcache->connect($obj["host"], $obj["port"]);
                    if (!$iscon) {
                        $this->memcache = null;
                    }
                } else {
                    $this->memcache->addServer($obj['host'], $obj['port']);
                }
            }
        }
    }
    /**
     * 关闭memcache
     */
    public function close()
    {
        if ($this->isEmptyWithConfig())
            return;
        $this->memcache->close();
        $this->memcache = NULL;
    }
    /**
     * 是否配置
     * @return bool
     */
    public function isEmptyWithConfig()
    {
        if ($this->memcache)
            return false;
        return true;
    }
    /**
     * 设定管理键
     * @param mixed $key 管理键
     */
    private function setMngKey($key)
    {
        $tablekey = $this->getKey();
        $memarray = $this->memcache->get($tablekey);
        if (!$memarray)
            $memarray = array();
        $memarray[$this->getKey($key)] = 1;
        $this->memSet($tablekey, $memarray, "函数:setMngKey");
    }

    /**
     * 缓存设置
     * @param mixed $key 数据键
     * @param mixed $data 写入数据
     */
    private function memSet($key, $data, $operdtype = "")
    {
        if ($this->memcache->set($key, $data) == false) {
            $this->memcache->flush();
            $this->writelog("memcache_full:{$key}:{$operdtype}", $data, "rm");
            $this->memcache->set($key, $data);
        }
    }

    #region Mem Members

    /**
     * 添加进缓存
     *
     * @param string $key 添加的键
     * @param array $array 对应内容
     */
    function set($key, $array)
    {
        if ($this->isEmptyWithConfig())
            return;
        //锁定缓存
        if ($this->lock()) {
            $this->setMngKey($key);
            $key = $this->getKey($key);
            $this->memSet($key, $array, "函数:set");
            $this->unlock();
        }
    }

    /**
     * 获取数据的逻辑
     *
     * @param string $key 键名
     *
     * @return array
     */
    function get($key)
    {
        if ($this->isEmptyWithConfig())
            return null;
        $this->transDel();
        $key = $this->getKey($key);
        return $this->memcache->get($key);
    }

    #endregion

    #region Mem Members

    /**
     * 刷新缓存
     */
    function flush()
    {
        if ($this->isEmptyWithConfig())
            return;
        $this->memcache->flush();
    }

    #endregion
}
